home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / cw_rgbslider.pro < prev    next >
Text File  |  1997-07-08  |  13KB  |  406 lines

  1. ; $Id: cw_rgbslider.pro,v 1.8 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1992-1997, Research Systems, Inc.  All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;    CW_RGBSLIDER
  8. ;
  9. ; PURPOSE:
  10. ;    CW_RGBSLIDER is a compund widget that provides three sliders for
  11. ;    adjusting color values. The RGB, CMY, HSV, and HLS color systems
  12. ;    can all be used. No matter which color system is in use,
  13. ;    the resulting color is always supplied in RGB, which is the
  14. ;    base system for IDL.
  15. ;
  16. ; CATEGORY:
  17. ;    Compound widgets.
  18. ;
  19. ; CALLING SEQUENCE:
  20. ;    Widget = CW_RGBSLIDER(Parent)
  21. ;
  22. ; INPUTS:
  23. ;       Parent:      The ID of the parent widget.
  24. ;
  25. ; KEYWORD PARAMETERS:
  26. ;    CMY:      If set, the initial color system used is CMY.
  27. ;    DRAG:      Set to zero if events should only be generated when
  28. ;          the mouse button is released. If this keyword is set,
  29. ;          events will be generated continuously when the sliders
  30. ;          are adjusted. Note: On slow systems, /DRAG performance
  31. ;          can be inadequate. The default is DRAG=0.
  32. ;    FRAME:      If set, a frame will be drawn around the widget. The
  33. ;          default is FRAME=0 (no frame drawn).
  34. ;    HSV:      If set, the initial color system used is HSV.
  35. ;    HLS:      If set, the initial color system used is HLS.
  36. ;    LENGTH:      The length of the sliders. The default = 256.
  37. ;    RGB:      If set, the initial color system used is RGB.
  38. ;          This is the default.
  39. ;    UVALUE:      The user value for the widget.
  40. ;    VERTICAL: If set, the sliders will be oriented vertically.
  41. ;          The default is VERTICAL=0 (horizontal sliders).
  42. ;    COLOR_INDEX: If set, display a small rectangle with the
  43. ;          selected color, using the given index.
  44. ;          The color is updated as the values are changed.
  45. ;
  46. ; OUTPUTS:
  47. ;       The ID of the created widget is returned.
  48. ;
  49. ; SIDE EFFECTS:
  50. ;    This widget generates event structures containing a three fields
  51. ;    named 'R', 'G', and 'B' containing the Red, Green, and Blue
  52. ;    components of the selected color.
  53. ;
  54. ; PROCEDURE:
  55. ;    The CW_RGBSLIDER widget has the following controls:
  56. ;
  57. ;    Color System Selection: A pulldown menu which allows the user
  58. ;        to change between the supported color systems.
  59. ;
  60. ;    Color adjustment sliders: Allow the user to select a new color
  61. ;        value. 
  62. ;
  63. ;    By adjusting these controls, the user selects color values which
  64. ;    are reported via the widget event mechanism.
  65. ;
  66. ; MODIFICATION HISTORY:
  67. ;    April 1, 1992, AB
  68. ;        Based on the RGB code from XPALETTE.PRO, but extended to
  69. ;        support color systems other than RGB.
  70. ;       7 April 1993, AB, Removed state caching.
  71. ;    10 May 1994, DMS, Added Color_index param to display color.
  72. ;-
  73.  
  74. pro CW_RGB_CHNG_CS, state, base_idx
  75.   ; Change the current color system.
  76.   ; State is the state structure to use (READ-ONLY)
  77.   ; base_idx is the index into state.select_b of the base to change to.
  78.  
  79.   case (base_idx) of
  80.     0: begin        ; RGB
  81.     WIDGET_CONTROL, state.r_sl, set_value=state.r_v
  82.     WIDGET_CONTROL, state.g_sl, set_value=state.g_v
  83.     WIDGET_CONTROL, state.b_sl, set_value=state.b_v
  84.     end
  85.     1: begin        ; CMY
  86.     WIDGET_CONTROL, state.c_sl, set_value=255-state.r_v
  87.     WIDGET_CONTROL, state.m_sl, set_value=255-state.g_v
  88.     WIDGET_CONTROL, state.y_sl, set_value=255-state.b_v
  89.         end
  90.     2: begin        ; HSV
  91.     COLOR_CONVERT, state.r_v, state.g_v, state.b_v, a, b, c, /RGB_HSV
  92.     WIDGET_CONTROL, state.hsv_h_sl, set_value=(state.h_v = a)
  93.     WIDGET_CONTROL, state.hsv_s_sl, set_value=(state.f1_v = b)
  94.     WIDGET_CONTROL, state.hsv_v_sl, set_value=(state.f2_v = c)
  95.     end
  96.     3: begin        ; HLS
  97.     COLOR_CONVERT, state.r_v, state.g_v, state.b_v, a, b, c, /RGB_HLS
  98.     WIDGET_CONTROL, state.hls_h_sl, set_value=(state.h_v = a)
  99.     WIDGET_CONTROL, state.hls_l_sl, set_value=(state.f1_v = b)
  100.     WIDGET_CONTROL, state.hls_s_sl, set_value=(state.f2_v = c)
  101.     end
  102.  
  103.   endcase
  104.  
  105.   ; Change the displayed slider base
  106.   WIDGET_CONTROL, map=0, state.select_b[state.curr_b_idx]
  107.   WIDGET_CONTROL, map=1, state.select_b[base_idx]
  108.   state.curr_b_idx = base_idx
  109. end
  110.  
  111.  
  112.  
  113. PRO CW_RGB_SET_DRAW, state
  114. if state.color_window lt 0 then begin    ;Initialize?
  115.     WIDGET_CONTROL, state.color_draw, GET_VALUE=i
  116.     swin = !d.window
  117.     WSET, i
  118.     state.color_window = i
  119.     ERASE, state.color_index        ;Set to our value
  120.     WSET, swin
  121.     endif
  122. TVLCT, state.r_v, state.g_v, state.b_v, state.color_index
  123. end
  124.  
  125.  
  126.  
  127.  
  128. function CW_RGB_EVENT, ev
  129.  
  130.   ; Recover the state of this compound widget
  131.   base = ev.handler
  132.   stash = WIDGET_INFO(base, /CHILD)
  133.   WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  134.  
  135.   case (ev.id) of
  136.     state.select_s : begin
  137.         if (state.curr_b_idx ne (ev.value-1)) then $
  138.         CW_RGB_CHNG_CS,state,ev.value-1
  139.     WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  140.         return, 0        ; Swallow the event
  141.       end
  142.  
  143.     state.r_sl: state.r_v = ev.value
  144.     state.g_sl: state.g_v = ev.value
  145.     state.b_sl: state.b_v = ev.value
  146.  
  147.     state.c_sl: state.r_v = 255 - ev.value
  148.     state.m_sl: state.g_v = 255 - ev.value
  149.     state.y_sl: state.b_v = 255 - ev.value
  150.  
  151.     state.hsv_h_sl: begin
  152.     state.h_v = ev.value
  153.     goto, calc_new_hsv
  154.     end
  155.     state.hsv_s_sl: begin
  156.     state.f1_v = ev.value
  157.     goto, calc_new_hsv
  158.     end
  159.     state.hsv_v_sl: begin
  160.     state.f2_v = ev.value
  161.       calc_new_hsv:
  162.     COLOR_CONVERT, state.h_v, state.f1_v, state.f2_v, a, b, c, /HSV_RGB
  163.     state.r_v = a
  164.         state.g_v = b
  165.     state.b_v = c
  166.     end
  167.     
  168.  
  169.     state.hls_h_sl: begin
  170.     state.h_v = ev.value
  171.     goto, calc_new_hls
  172.     end
  173.     state.hls_l_sl: begin
  174.     state.f1_v = ev.value
  175.     goto, calc_new_hls
  176.     end
  177.     state.hls_s_sl: begin
  178.     state.f2_v = ev.value
  179.       calc_new_hls:
  180.     COLOR_CONVERT, state.h_v, state.f1_v, state.f2_v, a, b, c, /HLS_RGB
  181.     state.r_v = a
  182.         state.g_v = b
  183.     state.b_v = c
  184.     end
  185.     
  186.   endcase
  187.  
  188.   if state.color_index ge 0 then CW_RGB_SET_DRAW, state
  189.  
  190.   ; Return an RGB event
  191.   ret = { RGB_EVENT, ID: base, TOP:ev.top, HANDLER:0L, $
  192.             R:state.r_v, G:state.g_v, B:state.b_v }
  193.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  194.   return, ret
  195.  
  196. end
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204. pro CW_RGB_SET_VAL, id, value
  205.  
  206.   ; Recover the state of this compound widget
  207.   stash = WIDGET_INFO(id, /CHILD)
  208.   WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  209.  
  210.   state.r_v = value[0]
  211.   state.g_v = value[1]
  212.   state.b_v = value[2]
  213.  
  214.   case (state.curr_b_idx) of
  215.     0: begin    ; RGB
  216.     WIDGET_CONTROL, state.r_sl, set_value=state.r_v
  217.     WIDGET_CONTROL, state.g_sl, set_value=state.g_v
  218.     WIDGET_CONTROL, state.b_sl, set_value=state.b_v
  219.     end
  220.     1: begin    ; CMY
  221.     WIDGET_CONTROL, state.c_sl, set_value=255-state.r_v
  222.     WIDGET_CONTROL, state.m_sl, set_value=255-state.g_v
  223.     WIDGET_CONTROL, state.y_sl, set_value=255-state.b_v
  224.         end
  225.     2: begin    ; HSV
  226.     COLOR_CONVERT, state.r_v, state.g_v, state.b_v, a, b, c, /RGB_HSV
  227.     WIDGET_CONTROL, state.hsv_h_sl, set_value=(state.h_v = a)
  228.     WIDGET_CONTROL, state.hsv_s_sl, set_value=(state.f1_v = b)
  229.     WIDGET_CONTROL, state.hsv_v_sl, set_value=(state.f2_v = c)
  230.     end
  231.     3: begin    ; HLS
  232.     COLOR_CONVERT, state.r_v, state.g_v, state.b_v, a, b, c, /RGB_HLS
  233.     WIDGET_CONTROL, state.hls_h_sl, set_value=(state.h_v = a)
  234.     WIDGET_CONTROL, state.hls_l_sl, set_value=(state.f1_v = b)
  235.     WIDGET_CONTROL, state.hls_s_sl, set_value=(state.f2_v = c)
  236.     end
  237.   endcase
  238.   if state.color_index ge 0 then CW_RGB_SET_DRAW, state
  239.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  240. end
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248. function CW_RGB_GET_VAL, id
  249.  
  250.   ; Recover the state of this compound widget
  251.   stash = WIDGET_INFO(id, /CHILD)
  252.   WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  253.  
  254.   ret = [ state.r_v, state.g_v, state.b_v ]
  255.  
  256.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  257.   return, ret
  258. end
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267. function CW_RGBSLIDER, parent, vertical=vertical, frame=frame, drag=drag, $
  268.                uvalue=uvalue, rgb=map_rgb, cmy=map_cmy, $
  269.             hsv=map_hsv, hls=map_hls, LENGTH = length, $
  270.             COLOR_INDEX=color_index
  271.  
  272.   IF NOT (KEYWORD_SET(drag))  THEN drag=0
  273.   IF NOT (KEYWORD_SET(frame))  THEN frame=0
  274.   IF NOT (KEYWORD_SET(vertical))  THEN vertical=0
  275.   IF NOT (KEYWORD_SET(uvalue))  THEN uvalue=0
  276.   IF NOT (KEYWORD_SET(length))  THEN length=256
  277.   IF N_ELEMENTS(Color_index) le 0 then color_index=-1
  278.  
  279.   map_rgb = KEYWORD_SET(map_rgb)
  280.   map_cmy = KEYWORD_SET(map_cmy)
  281.   map_hsv = KEYWORD_SET(map_hsv)
  282.   map_hls = KEYWORD_SET(map_hls)
  283.   ; Make sure only one color system is selected.
  284.   junk = map_rgb + map_cmy + map_hsv + map_hls
  285.   if (junk eq 0) then map_rgb = 1    ; RGB is the default
  286.   if (junk gt 1) then $
  287.     message, 'The RGB, CMY, HSV, and HLS keywords are mutually exclusive.'
  288.  
  289.   ; The variables in the state struct have suffixes that identify their class
  290.   ;    _b - The various slider bases
  291.   ;    _s - The pulldown menu selection buttons
  292.   ;     _sl - The sliders
  293.   ;     _v - Current values in various systems
  294.   state = { CW_RGBSLIDER_STATE, $
  295.         r_v:0B, g_v:0B, b_v:0B, $        ; Current RGB for all C.S.
  296.         h_v:0.0, f1_v:0.0, f2_v:0.0, $    ; Curr. for HLS and HSV
  297.         r_sl:0L, g_sl:0L, b_sl:0L, $    ; RGB sliders
  298.         c_sl:0L, m_sl:0L, y_sl:0L, $    ; CMY sliders
  299.         hsv_h_sl:0L, hsv_s_sl:0L, hsv_v_sl:0L, $    ; HSV sliders
  300.         hls_h_sl:0L, hls_l_sl:0L, hls_s_sl:0L, $    ; HLS sliders
  301.         select_s:0L, select_b:lonarr(4), curr_b_idx:0L, $ ;Slider bases
  302.         first_child:0L, $            ; Where the state is kept
  303.         color_index: long(color_index), $
  304.         color_window: -1L, $
  305.         color_draw: 0L }
  306.  
  307.   on_error,2              ;Return to caller if an error occurs
  308.  
  309.   base = WIDGET_BASE(parent, /COLUMN, FRAME=frame, EVENT_FUNC='CW_RGB_EVENT',$
  310.         FUNC_GET_VALUE='CW_RGB_GET_VAL', PRO_SET_VALUE='CW_RGB_SET_VAL', $
  311.     UVALUE=uvalue)
  312.   junk = { CW_PDMENU_S, flags:0, name:'' }
  313.  
  314.   junk1 = WIDGET_BASE(base, /ROW)
  315.   state.select_s=CW_PDMENU(junk1, [ { CW_PDMENU_S, 1, 'Select Color System' },$
  316.     { CW_PDMENU_S, 0, 'RGB  (Red/Green/Blue)' }, $
  317.     { CW_PDMENU_S, 0, 'CMY  (Cyan/Magenta/Yellow)' }, $
  318.     { CW_PDMENU_S, 0, 'HSV  (Hue/Saturation/Value)' }, $
  319.     { CW_PDMENU_S, 0, 'HLS  (Hue/Lightness/Saturation)' }])
  320.   if color_index gt 0 then $
  321.     state.color_draw = WIDGET_DRAW(junk1, xsize=24, ysize=24, RET=2)
  322.  
  323.   selbase = WIDGET_BASE(base)
  324.  
  325.   fslide_fmt = '(F4.2)'
  326.   if (vertical eq 0) then begin
  327.     tmp = WIDGET_BASE(selbase, /COLUMN, /MAP)
  328.       state.r_sl = WIDGET_SLIDER(tmp, max=255, title='Red', $
  329.                   drag=drag, xsize=length)
  330.       state.g_sl = WIDGET_SLIDER(tmp, max=255, title='Green', $
  331.                  drag=drag, xsize=length)
  332.       state.b_sl = WIDGET_SLIDER(tmp, max=255, title='Blue', $
  333.                  drag=drag, xsize=length)
  334.       state.select_b[0] = tmp
  335.     tmp = WIDGET_BASE(selbase, /COLUMN, MAP=0)
  336.       state.c_sl = WIDGET_SLIDER(tmp, max=255, title='Cyan', $
  337.                  drag=drag, xsize=length)
  338.       state.m_sl = WIDGET_SLIDER(tmp, max=255, title='Magenta', $
  339.                  drag=drag, xsize=length)
  340.       state.y_sl = WIDGET_SLIDER(tmp, max=255, title='Yellow', $
  341.                  drag=drag, xsize=length)
  342.       state.select_b[1] = tmp
  343.     tmp = WIDGET_BASE(selbase, /COLUMN, MAP=0)
  344.       state.hsv_h_sl = WIDGET_SLIDER(tmp, max=360, title='Hue', $
  345.                      drag=drag, xsize=length)
  346.       state.hsv_s_sl = CW_FSLIDER(tmp, max=1.0, title='Saturation', $
  347.                       drag=drag, xsize=length, format=fslide_fmt)
  348.       state.hsv_v_sl = CW_FSLIDER(tmp, max=1.0, title='Value', $
  349.                       drag=drag, xsize=length, format=fslide_fmt)
  350.       state.select_b[2] = tmp
  351.     tmp = WIDGET_BASE(selbase, /COLUMN, MAP=0)
  352.       state.hls_h_sl = WIDGET_SLIDER(tmp, max=360, title='Hue', $
  353.                          drag=drag, xsize=length)
  354.       state.hls_l_sl = CW_FSLIDER(tmp, max=1.0, title='Lightness', $
  355.                       drag=drag, xsize=length, format=fslide_fmt)
  356.       state.hls_s_sl = CW_FSLIDER(tmp, max=1.0, title='Saturation', $
  357.                       drag=drag, xsize=length, format=fslide_fmt)
  358.       state.select_b[3] = tmp
  359.   endif else begin                ; Vertical sliders
  360.     tmp = WIDGET_BASE(selbase, /ROW, /MAP)
  361.       state.r_sl = WIDGET_SLIDER(tmp, max=255, title='R',drag=drag, $
  362.                  ysize=length, /vertical)
  363.       state.g_sl = WIDGET_SLIDER(tmp, max=255, title='G', $
  364.                  drag=drag, ysize=length, /vertical)
  365.       state.b_sl = WIDGET_SLIDER(tmp, max=255, title='B', $
  366.                  drag=drag, ysize=length, /vertical)
  367.       state.select_b[0] = tmp
  368.     tmp = WIDGET_BASE(selbase, /ROW, MAP=0)
  369.       state.c_sl = WIDGET_SLIDER(tmp, max=255, title='C', $
  370.                  drag=drag, ysize=length, /vertical)
  371.       state.m_sl = WIDGET_SLIDER(tmp, max=255, title='M', $
  372.                  drag=drag, ysize=length, /vertical)
  373.       state.y_sl = WIDGET_SLIDER(tmp, max=255, title='Y', $
  374.                  drag=drag, ysize=length, /vertical)
  375.       state.select_b[1] = tmp
  376.     tmp = WIDGET_BASE(selbase, /ROW, MAP=0)
  377.       state.hsv_h_sl = WIDGET_SLIDER(tmp, max=360, title='H', $
  378.                      drag=drag, ysize=length, /vertical)
  379.       state.hsv_s_sl = CW_FSLIDER(tmp, max=1.0, title='S', $
  380.                    drag=drag, ysize=length, /vertical, $
  381.                    format=fslide_fmt)
  382.       state.hsv_v_sl = CW_FSLIDER(tmp, max=1.0, title='V', $
  383.                    drag=drag, ysize=length, /vertical, $
  384.                    format=fslide_fmt)
  385.       state.select_b[2] = tmp
  386.     tmp = WIDGET_BASE(selbase, /ROW, MAP=0)
  387.       state.hls_h_sl = WIDGET_SLIDER(tmp, max=360, title='H', $
  388.                          drag=drag, ysize=length, /vertical)
  389.       state.hls_l_sl = CW_FSLIDER(tmp, max=1.0, title='L',drag=drag,$
  390.                       ysize=length, /vertical, format=fslide_fmt)
  391.       state.hls_s_sl = CW_FSLIDER(tmp, max=1.0, title='S',drag=drag,$
  392.                       ysize=length, /vertical, format=fslide_fmt)
  393.       state.select_b[3] = tmp
  394.   endelse
  395.  
  396.   ; Stash the state
  397.   WIDGET_CONTROL, WIDGET_INFO(base, /CHILD), SET_UVALUE=state, /NO_COPY
  398.  
  399.   ; If the initial color system is not RGB, switch it now before it's realized
  400.   if (map_cmy) then CW_RGB_CHNG_CS, nstate, 1
  401.   if (map_hsv) then CW_RGB_CHNG_CS, nstate, 2
  402.   if (map_hls) then CW_RGB_CHNG_CS, nstate, 3
  403.  
  404.   return, base
  405. end
  406.